package com.vogtec.fota.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.vogtec.fota.config.Config;
import com.vogtec.fota.dao.BikeDao;
import com.vogtec.fota.dao.FirmWareDao;
import com.vogtec.fota.dao.UpgradeTaskDao;
import com.vogtec.fota.dao.model.Bike;
import com.vogtec.fota.dao.model.FirmWare;
import com.vogtec.fota.dao.model.UpgradeTask;
import com.vogtec.fota.entity.UpgradeTask.*;
import com.vogtec.fota.mqtt.StartUpgrade;
import com.vogtec.fota.quartz.FinishSchedule;
import com.vogtec.fota.quartz.StartSchedule;
import com.vogtec.fota.service.UpgradeTaskService;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.ArrayList;

/**
 * Created by wei on 2017/7/3.
 */
@Service
public class UpgradeTaskServiceImpl implements UpgradeTaskService{

    private static final Logger log = LoggerFactory.getLogger(UpgradeTaskServiceImpl.class);

    @Autowired
    private UpgradeTaskDao upgradeTaskDao;

    @Autowired
    private BikeDao bikeDao;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private StartUpgrade startUpgrade;

    @Autowired
    private FirmWareDao firmWareDao;

    @Autowired
    private StartSchedule startSchedule;

    @Autowired
    private FinishSchedule finishSchedule;

    @Override
    public AddUpgradeTaskResult addUpgradeTask(AddUpgradeTask aut) {
        AddUpgradeTaskResult autr = new AddUpgradeTaskResult();

        UpgradeTask upgradeTask = null;
        try{
            String json = objectMapper.writeValueAsString(aut);
            upgradeTask = objectMapper.readValue(json, UpgradeTask.class);

            FirmWare firmWare = firmWareDao.selectFWById(aut.getId());

            upgradeTask.setFirmWareId(firmWare.getId());
            upgradeTask.setFirmWareVersion(firmWare.getFirmWareVersion());
            upgradeTask.setProductModel(firmWare.getProductModel());
            upgradeTask.setFirmWareName(firmWare.getFirmWareName());

            int value = upgradeTaskDao.insert(upgradeTask);

            //新增任务车辆bikes
            ArrayList<String> bikesNumList = aut.getBikeNumList();
            for(String b : bikesNumList){
                Bike bike = new Bike();
                bike.setBikeNum(b);
                bike.setStatus(0);
                bike.setUpgradeTask(upgradeTask.getId());

                log.debug("******* addUpgradeTask : bike.upgradeTask[{}] *******",String.valueOf(bike.getUpgradeTask()));

                bikeDao.insert(bike);
            }

            startSchedule.main(upgradeTask.getStartTime(),upgradeTask.getId());
            finishSchedule.main(upgradeTask.getEndTime(), upgradeTask.getId());

            switch (value){
                case 1:
                    autr.setResult("SUCCESS");
                    autr.setUpgradeTask(upgradeTask);
                    log.info("insert success!!!");
                    break;
                case 0:
                    autr.setResult("FAIL");
                    autr.setDescription("服务器出错");
                    log.error("insert fail!!!");
                    //此处做失败处理
                    return autr;
            }

        }catch (Exception e) {
            log.error("", e);
        }
        //此处做成功处理
        return autr;
    }

    @Override
    public TaskQueryRusult taskQuery(Integer id) {
        TaskQueryRusult tqr = new TaskQueryRusult();

        UpgradeTask upgradeTask = upgradeTaskDao.selectByid(id);
        if(upgradeTask != null){
            tqr.setResult("SUCCESS");
            tqr.setUpgradeTask(upgradeTask);
            log.info("upgradeTask :" + upgradeTask.toString());
        }else{
            tqr.setResult("FAIL");
            tqr.setDescription("服务器出错");
            log.error("id [" + id + "]'s upgradeTask is null!!!");
        }
        return tqr;
    }

    @Override
    public QueryStatusResult taskQueryByStatus(String taskStatus,Integer pageNo,Integer pageSize) {
        QueryStatusResult qsr = new QueryStatusResult();

        int total = 0;

        Page<UpgradeTask> page = PageHelper.startPage(pageNo, pageSize);
        if(taskStatus.equals("2")||taskStatus.equals("3")){
            upgradeTaskDao.selectFinish();
            total = upgradeTaskDao.selectCountByStatus("2") + upgradeTaskDao.selectCountByStatus("3");
        }else{
            upgradeTaskDao.selectByStatus(taskStatus);
            total = upgradeTaskDao.selectCountByStatus(taskStatus);
        }
        if(page != null){
            qsr.setResult("SUCCESS");
            qsr.setTaskList(page);
            qsr.setTotal(total);
            log.info("the attentionTotal of taskList: " + String.valueOf(page.getTotal()));
        }else{
            qsr.setResult("FAIL");
            qsr.setDescription("服务器出错");
            log.error("status [" + taskStatus + "]'s taskList is null!!!");
        }
        return qsr;
    }

    @Override
    public QueryAllResult queryAll(Integer pageNo,Integer pageSize) {

        QueryAllResult qar = new QueryAllResult();

        int total = upgradeTaskDao.selectCountAll();

        Page<UpgradeTask> page = PageHelper.startPage(pageNo, pageSize);
        upgradeTaskDao.selectAllDetail();
        if(page != null){
            qar.setResult("SUCCESS");
            qar.setTaskList(page);
            qar.setTotal(total);
            log.info("the attentionTotal of taskList: " + page.getTotal());
        }else{
            qar.setResult("FAIL");
            qar.setDescription("服务器出错");
            log.error("something wrong");
        }
        return qar;
    }

    @Override
    public StartResult startTask(Integer id) throws MqttException{

        log.info("****** in startTask ******");

        StartResult startResult = new StartResult();

        int status = upgradeTaskDao.selectByid(id).getTaskStatus();

        if(status == 2 || status == 3){
            startResult.setResult("FAIL").setDescription("此任务已升级完毕，请勿重复操作");
            return startResult;
        }

        Timestamp realStartTime = new Timestamp(System.currentTimeMillis());
        upgradeTaskDao.updateStartTime(realStartTime,id);

        //此处可能需要分批次处理
        ArrayList<Bike> bikeList = bikeDao.selectBikes(id);

        //设置全局变量taskId
        Config.taskId = id;

        log.debug("****** bikeList of [{}] is [{}] ******",id,bikeList);

        Bike bike = null;

        for(int i = 0; i< bikeList.size(); i++){
            bike = bikeList.get(i);

            log.debug("****** bikeNum : [{}] ******",bike.getBikeNum());

            String url = firmWareDao.selectFWById(upgradeTaskDao.selectByid(id).getFirmWareId()).getFirmWareUrl();

            startUpgrade.publish(bike.getBikeNum(), (byte) 0, url,"$client/bike:" + bike.getBikeNum());

        }

        startResult.setResult("SUCCESS");
        return startResult;
    }

    @Override
    public FinishResult finishTask(Integer id) {

        FinishResult finishResult = new FinishResult();
        String comp = upgradeTaskDao.selectByid(id).getCompletion();
//        if(comp.equals("100%")){}
        if(!comp.equals("1.0")){
            upgradeTaskDao.updateStatus(3,id);
        }
        finishResult.setResult("SUCCESS");

        return finishResult;
    }

    @Override
    public DeleteResult deleteTask(Integer id) {
        DeleteResult dr = new DeleteResult();

        bikeDao.delete(id);
        int value = upgradeTaskDao.delete(id);

        switch (value){
            case 1:
                dr.setResult("SUCCESS");
                log.info("delete success!!!");
                break;
            default:
                dr.setResult("FAIL");
                dr.setDescription("服务器出错");
                log.info("delete fail!!!");
                //做失败处理
        }
        return dr;
    }

}
